package com.smartfast4j.backend.modules.sys.security.shiro.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.smartfast4j.backend.common.bean.R;
import com.smartfast4j.backend.common.util.WebUtil;
import org.apache.log4j.Logger;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义Shiro 访问权限拦截器
 * Created by gacl on 2017/9/9.
 */
public class PermissionFilter extends AccessControlFilter {

    private static final Logger logger = Logger.getLogger(PermissionFilter.class);

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) throws Exception {
        logger.debug("进入PermissionFilter→isAccessAllowed方法处理用户请求");
        Map<String, String> params = WebUtil.getRequestParams(servletRequest);
        logger.debug("进入PermissionFilter→isAccessAllowed方法处理用户请求，params="+ JSON.toJSONString(params));
        //先判断带参数的权限判断
        Subject subject = getSubject(servletRequest, servletResponse);
        if(null != mappedValue){
            String[] arra = (String[])mappedValue;
            for (String permission : arra) {
                if(subject.isPermitted(permission)){
                    return Boolean.TRUE;//返回true之后就会继续往下执行，不会进入onAccessDenied方法
                }
            }
        }
        HttpServletRequest httpRequest = ((HttpServletRequest)servletRequest);
        /**
         * 此处是改版后，为了兼容项目不需要部署到root下，也可以正常运行，但是权限没设置目前必须到root 的URI，
         * 原因：如果你把这个项目叫 ShiroDemo，那么路径就是 /ShiroDemo/xxxx.shtml ，那另外一个人使用，又叫Shiro_Demo,那么就要这么控制/Shiro_Demo/xxxx.shtml
         * 理解了吗？
         * 所以这里替换了一下，使用根目录开始的URI
         */

        String uri = httpRequest.getRequestURI();//获取URI
        String basePath = httpRequest.getContextPath();//获取basePath
        if(null != uri && uri.startsWith(basePath)){
            uri = uri.replace(basePath, "");
        }
        if(subject.isPermitted(uri)){
            return Boolean.TRUE;//返回true之后就会继续往下执行，不会进入onAccessDenied方法
        }
        return Boolean.FALSE;//返回false之后就会进入onAccessDenied
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        logger.debug("进入PermissionFilter→onAccessDenied方法处理用户请求");
        Subject subject = getSubject(servletRequest, servletResponse);
        if (null == subject.getPrincipal()) {//表示没有登录
            if(ShiroFilterUtils.isAjax(servletRequest)){
                ShiroFilterUtils.out(servletResponse);
            }else{
                ShiroFilterUtils.out(servletResponse, R.error(-1,"登录已经失效，请重新登录"));
            }
        } else {
            ShiroFilterUtils.out(servletResponse,  R.error("没有权限，请联系管理员授权"));
        }
        return Boolean.FALSE;//返回false之后就会进入onAccessDenied
    }
}
